﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using ScrumDashboard.Library.Model;

namespace ScrumDashboard.Library.Tfs
{
    /// <summary>
    /// Responsible for creating business classes from TFS classes
    /// </summary>
    public static class ObjectFactory
    {
        public const string CommonSelectFields = "[System.Id],[System.Rev],[System.Title],[System.State],[System.CreatedDate],[System.AssignedTo],[System.ChangedDate],[System.ChangedBy],[System.WorkItemType],[Conchango.TeamSystem.Scrum.EstimatedEffort],[Conchango.TeamSystem.Scrum.WorkRemaining],[System.TeamProject]";
        public const string ProductBacklogFields = CommonSelectFields + ",[System.IterationId],[System.IterationPath],[Conchango.TeamSystem.Scrum.BusinessPriority],[Conchango.TeamSystem.Scrum.DeliveryOrder],[Conchango.TeamSystem.Scrum.Team],[System.Description]";
        public const string SprintBacklogFields = CommonSelectFields + ",[Conchango.TeamSystem.Scrum.Team],[System.WorkItemType]";
        public const string SprintItemFields = CommonSelectFields + ",[Conchango.TeamSystem.Scrum.SprintStart],[Conchango.TeamSystem.Scrum.SprintEnd],[System.Description]";

        private static void InteralSetCommonValues(BacklogItem bi, WorkItem wi, User assignedTo)
        {
            bi.Id = wi.Id;
            bi.RevisionId = wi.Revision;
            bi.Title = wi.Title;
            bi.State = wi.State;
            bi.Created = wi.CreatedDate;
            bi.AssignedTo = assignedTo;
            bi.Changed = wi.ChangedDate;
            bi.ChangedBy = wi.ChangedBy;
            if (wi.GetWorkItemType() != "Impediment")
            {
                bi.EstimatedEffort = wi.Fields[ConchangoFields.EstimatedEffort].Value != null ? (double)wi.Fields[ConchangoFields.EstimatedEffort].Value : 0;
                bi.WorkRemaining = wi.Fields[ConchangoFields.WorkRemaining].Value != null ? (double)wi.Fields[ConchangoFields.WorkRemaining].Value : 0;
            }
        }

        public static ProductBacklogItem CreateProductBacklogItem(WorkItem pbiSource, User assignedTo)
        {
            ProductBacklogItem pbi = new ProductBacklogItem();
            InteralSetCommonValues(pbi, pbiSource,assignedTo);
            pbi.BusinessPriority = pbiSource.Fields[ConchangoFields.BusinessPriority].Value != null ? (int)pbiSource.Fields[ConchangoFields.BusinessPriority].Value : 0;
            pbi.DeliveryOrder = pbiSource.Fields[ConchangoFields.DeliveryOrder].Value != null ? (int)pbiSource.Fields[ConchangoFields.DeliveryOrder].Value : 0;

            if (pbiSource.Fields[ConchangoFields.Team].Value != null)
                pbi.Team = pbiSource.Fields[ConchangoFields.Team].Value.ToString();
            if (pbiSource.Description != null)
                pbi.Description = pbiSource.Description;

            pbi.SprintNumber = pbiSource.IterationId;
            pbi.SprintName = pbiSource.IterationPath;
            if (pbi.SprintName.StartsWith(pbiSource.GetTeamProject()))
                pbi.SprintName = pbi.SprintName.Substring(pbiSource.GetTeamProject().Length);

            LinkCollection links = pbiSource.Links;

            foreach (Link l in links)
            {
                if (l is RelatedLink)
                {
                    pbi.RelatedWorkItems.Add(((RelatedLink)l).RelatedWorkItemId);
                }
            }

            return pbi;
        }

        public static SprintBacklogItem CreateSprintBacklogItem(WorkItem sbiSource, User assignedTo)
        {
            SprintBacklogItem sbi = new SprintBacklogItem();
            InteralSetCommonValues(sbi, sbiSource,assignedTo);
            sbi.BacklogType = sbiSource.GetWorkItemType();
            if (sbiSource.Fields[ConchangoFields.Team].Value != null)
                sbi.Team = sbiSource.Fields[ConchangoFields.Team].Value.ToString();

            return sbi;
        }

        public static SprintItem CreateSprintItem(WorkItem sprintSource)
        {
            // Do a smoke test for a Conchango v2 property first so references
            // into older projects don't cause exceptions from for example Import Bugs
            if (!sprintSource.Fields.Contains(ConchangoFields.SprintStart))
                return null;

            SprintItem sprint = new SprintItem() { Id = sprintSource.Id, Title = sprintSource.IterationPath, SprintNumber = (int)sprintSource.IterationId, ProjectName = sprintSource.GetTeamProject() };
            sprint.SprintStart = sprintSource.Fields[ConchangoFields.SprintStart].Value != null ? (DateTime)sprintSource.Fields[ConchangoFields.SprintStart].Value : DateTime.Now;
            sprint.SprintEnd = sprintSource.Fields[ConchangoFields.SprintEnd].Value != null ? (DateTime)sprintSource.Fields[ConchangoFields.SprintEnd].Value : DateTime.Now;
            sprint.Goal = sprintSource.Description != null ? sprintSource.Description : "";

            if (sprint.Title.StartsWith(sprintSource.GetTeamProject()))
                sprint.Title = sprint.Title.Substring(sprintSource.GetTeamProject().Length);
            return sprint;
        }
    }
}
